﻿using System;
using System.Collections.Generic;
using System.Text;

namespace RayD.Repository.Core
{
    /// <summary>
    /// Element树形结构实体
    /// </summary>
    public class TreeModel
    {
        /// <summary>
        /// 节点id
        /// </summary>
        public string id { get; set; }
        /// <summary>
        /// 父节点Id
        /// </summary>
        public string parentId { get; set; }
        /// <summary>
        /// 节点值(选则的值)
        /// </summary>
        public string value { get; set; }
        /// <summary>
        /// 节点显示名
        /// </summary>
        public string label { get; set; }
        /// <summary>
        /// 节点图标
        /// </summary>
        public string icon { get; set; }  
        /// <summary>
        /// 是否为叶子节点( 懒加载有效 )
        /// </summary>
        public bool isLeaf { get; set; }
        /// <summary>
        /// 子节点
        /// </summary>
        public List<TreeModel> children { get; set; }

        /// <summary>
        /// 是否有子节点
        /// </summary>
        public bool hasChildren { get; set; }
        /// <summary>
        /// 子节点是否已经加载完成了
        /// </summary>
        public bool complete { get; set; }
    }


    /// <summary>
    /// List<TreeModel> 的拓展类
    /// </summary>
    public static partial class Extention
    {
        /// <summary>
        /// 树形数据转化
        /// </summary>
        /// <param name="list">数据</param>
        /// <returns></returns>
        public static List<TreeModel> ToTree(this List<TreeModel> list, string parentId = "")
        {
            Dictionary<string, List<TreeModel>> childrenMap = new Dictionary<string, List<TreeModel>>();
            Dictionary<string, TreeModel> parentMap = new Dictionary<string, TreeModel>();
            List<TreeModel> res = new List<TreeModel>();

            //首先按照
            foreach (var node in list)
            {
                node.hasChildren = false;
                node.complete = true;
                // 注册子节点映射表
                if (!childrenMap.ContainsKey(node.parentId))
                {
                    childrenMap.Add(node.parentId, new List<TreeModel>());
                }
                else if (parentMap.ContainsKey(node.parentId))
                {
                    parentMap[node.parentId].hasChildren = true;
                }
                childrenMap[node.parentId].Add(node);
                // 注册父节点映射节点表
                parentMap.Add(node.id, node);

                // 查找自己的子节点
                if (!childrenMap.ContainsKey(node.id))
                {
                    childrenMap.Add(node.id, new List<TreeModel>());
                }
                else
                {
                    node.hasChildren = true;
                }
                node.children = childrenMap[node.id];
            }

            if (string.IsNullOrEmpty(parentId))
            {
                // 获取祖先数据列表
                foreach (var item in childrenMap)
                {
                    if (!parentMap.ContainsKey(item.Key))
                    {
                        res.AddRange(item.Value);
                    }
                }
            }
            else
            {
                if (childrenMap.ContainsKey(parentId))
                {
                    return childrenMap[parentId];
                }
                else
                {
                    return new List<TreeModel>();
                }
            }
            return res;
        }
        /// <summary>
        /// 遍历树形数据获取全部子节点ID
        /// </summary>
        /// <param name="list">树形数据列表</param>
        /// <param name="outList">输出数据列表</param>
        public static void GetSubNodes(this List<TreeModel> list, List<string> outList)
        {
            foreach (var item in list)
            {
                outList.Add(item.id);
                if (item.hasChildren && item.children?.Count > 0)
                {
                    GetSubNodes(item.children, outList);
                }
            }
        }
    }
}
